<?php
/**
 * ResMania
 * More Information contact: info@resmania.com
 *
 * @package ResMania - Joomla Connector.
 * @version 0.5
 * @author webformatique
 * @copyright (C) 2010- webformatique
 * @license GNU/GPLv3 http://www.gnu.org/copyleft/gpl.html
 */

// no direct access
defined('_JEXEC') or die('Restricted access');

include_once JPATH_ROOT . DS. 'RM' . DS . 'system' . DS . 'application' . DS . 'classes' . DS . 'RM' . DS . 'Connector.php';

class RM_Joomla_Connector extends RM_Connector {
    /**
     * Perform front end user CMS authentication.
     *
     * @param string $username
     * @param string $password
     * @return bool
     */
    function authenticate($username, $password)
    {
        $credentials = array(
            'username' => $username,
            'password' => $password
        );
        $mainframe =& JFactory::getApplication('site');
        return $mainframe->login($credentials, array());
    }

    public static function is15(){
        $versionClass = new JVersion();
        $version = $versionClass->getShortVersion();
        return version_compare($version, '1.6.0', '<');
    }

    public static function is16(){
        $versionClass = new JVersion();
        $version = $versionClass->getShortVersion();
        return version_compare($version, '1.6.0', '>=');
    }

    protected function _getExtraPathes(){
        return array($this->_rootPath . DS . 'administrator' . DS . 'components' . DS . 'com_resmania' . DS . 'classes');
    }

    public function getDefaultUnitListLength(){
        $jconfig = new jconfig();
        return $jconfig->list_limit;
    }

    public function __construct($module){
        if (self::is15()) {
            spl_autoload_register('__autoload');
        } else if (self::is16()) {
            spl_autoload_register(array('JLoader','load'));
        }
        $this->_module = $module;
        $this->_rootPath = JPATH_ROOT;
    }

    public function initDB(){
        $this->_config = $this->_getConfig();
        parent::initDB();
    }

    public function initConfig(){
        $this->_locale = $this->_getLocale();
        $this->_router = $this->_getRouter();
        parent::initConfig();
    }

    public function getUser(){
        $user = & JFactory::getUser();
        return new RM_Joomla_User($user);
    }

    public function getLoginStatus(){
        $user = & JFactory::getUser();
        $id = $user->get('id');
        if (isset($id) && $id !=""){
            return true;
        }
        return false;
    }

    /**
     * Returns all CMS users in RM_User_CMS_Interface wrappers
     *
     * @return array
     */
    public function getUsers()
    {
        $users = array();
        $ids = $this->_getRegisteredUsersIDs();
        foreach ($ids as $id){
            $joomlaUser = new JUser($id);
            $users[] = new RM_Joomla_User($joomlaUser);
        }
        return $users;
    }

    /**
     * Returns all 'Registered' users IDs
     *
     * @return array
     */
    protected function _getRegisteredUsersIDs()
    {
        if (self::is15()) {
            return $this->_getRegisteredUsersIDs15();
        }
        if (self::is16()) {
            return $this->_getRegisteredUsersIDs16();
        }
        return array();
    }

    /**
     * @return array
     */
    protected function _getRegisteredUsersIDs15()
    {
        $query = "SELECT a.id FROM #__users AS a WHERE a.usertype = 'Registered'";
        $db =& JFactory::getDBO();
		$db->setQuery( $query );
		$result = $db->loadResultArray();
        if ($result == null) {
            return array();
        }
        return $result;
    }

    /**
     * @todo: in fact in Joomla 1.6 super admin could do anything with user groups and permissions,
     * so we basically try to  to find users of default 'Customer Group'
     * @return array
     */
    protected function _getRegisteredUsersIDs16()
    {
        $query = "SELECT u.id FROM #__users AS u
            LEFT OUTER JOIN #__user_usergroup_map as ugm ON ugm.user_id=u.id
            INNER JOIN #__usergroups ug ON ug.id=ugm.group_id AND ug.title='Registered'";
		$db =& JFactory::getDbo();
		$db->setQuery( $query );
		$result = $db->loadResultArray();
        if ($result == null) {
            return array();
        }
        return $result;
    }

    /* (non-PHPdoc)
     * @see system/application/classes/RM/RM_Connector#getLocale()
     */
    protected function _getLocale(){
        $model = new RM_Languages();
        $defaultCoreLocale = $model->getDefaultLocale();
        if (self::is15()){
            $joomlaLocales = JFactory::getLanguage()->getLocale();
            if (is_array($joomlaLocales) == false){
                $joomlaLocale = $joomlaLocales;
            } elseif (count($joomlaLocales) == 0) {
                return $defaultCoreLocale;
            } else {
                $joomlaLocale = $joomlaLocales[0];
            }

            list($locale, $charset) = explode('.', $joomlaLocale);
        } elseif (self::is16()) {
            $joomlaTag = JFactory::getLanguage()->getTag();
            $locale = str_replace('-', '_', $joomlaTag);
        } else {
            return $defaultCoreLocale;
        }
        return $model->find($locale)->current()->iso;
    }

    /**
     * Returns array of SQL queries for database installation
     *
     * @return array
     */
    private function getInstallSQL(){
        $filename = JPATH_ROOT . DIRECTORY_SEPARATOR . 'RM' . DIRECTORY_SEPARATOR . 'system' . DIRECTORY_SEPARATOR . 'sql' . DIRECTORY_SEPARATOR . 'install.sql';
	    return $this->_getSQL($filename);
    }

    /**
     * Returns sql queries from file
     *
     * @param string $filename - fullpath to file
     * @return array - array with SQL queries
     */
    private function _getSQL($filename){
        $sqlString = file_get_contents($filename);
        $lines = explode("\r", $sqlString);
        foreach ($lines as $key => $line) {
            if (substr(ltrim($line), 0, 2) == '--' || ltrim($line) == '') {
            unset($lines[$key]);
            }
        }
        $sqlString = implode("\r", $lines);
        $sql = explode(";\r", $sqlString);
        return $sql;
    }

    /**
     * Returns array of SQL queries for database uninstall
     *
     * @return array
     */
    private function getUninstallSQL(){
        $filename = JPATH_ROOT . DIRECTORY_SEPARATOR . 'RM' . DIRECTORY_SEPARATOR . 'system' . DIRECTORY_SEPARATOR . 'sql' . DIRECTORY_SEPARATOR . 'uninstall.sql';
        return $this->_getSQL($filename);
    }

    protected function _getRouter(){
        $router = new RM_Joomla_Controller_Router($this->getModule());
        $router->addRoute('default',new RM_Joomla_Controller_Router_Route (
            array(
                'module' => $this->_module,
                'controller' => 'Index',
                'action' => 'index',
            )
        ));
        return $router;
    }

    /**
     * Returns root url to cms
     *
     * @return string
     */
    public function getRootURL(){
        return JURI::root();
    }

    /**
     * Returns root admin URL for CMS
     *
     * @return string Root URL
     */
    public function getAdminRootURL(){
        return JURI::root().'administrator/';
    }

    /**
     * Returns root user URL for CMS
     *
     * @return string Root URL
     */
    public function getUserRootUrl(){
        return JURI::root();
    }

    /* (non-PHPdoc)
     * @see system/application/classes/RM/RM_Connector#getConfig()
     */
    protected function _getConfig(){
        $jConfig = new jconfig();

        $parameters = array();
        if (strpos(strtolower($jConfig->host), '.sock') === false) {
            if (strpos($jConfig->host, ':') === false) {
                $parameters['host'] = $jConfig->host;
            } else {
                list($host, $port) = explode(':', $jConfig->host);
                $parameters['host'] = $host;
                $parameters['port'] = $port;
            }
        } else {
            if (strpos($jConfig->host, ':') === false) {
                $socket = $jConfig->host;
            } else {
                list($host, $socket, $port) = explode(':', $jConfig->host);
            }
            $parameters['unix_socket'] = $socket;
        }
        $parameters['username'] = $jConfig->user;
        $parameters['password'] = $jConfig->password;
        $parameters['dbname'] = $jConfig->db;

        //TODO: adapter selecting should be moved to parent (RM_Connector) class to be available for all child classes.
        if (extension_loaded('pdo_mysql')) {
            $adapter = 'PDO_MYSQL';
            //This line should remove error:
            //SQLSTATE[HY000]: General error: 2014 Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll().
            //from Windows installation of PDO php extension
            $parameters['driver_options'] = array(
                PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true
            );
        } elseif (function_exists('mysqli_connect')) {
            $adapter = 'Mysqli';
        } else {
            //No PDO and MySQLi extensions installed. We need to finish our work with BIG error on the screen.
            ob_clean();
            echo "ERROR: Resmania will not work without PHP extensions: 'pdo_mysql' or 'mysqli'.";
            die();
        }

        $configArray = array(
            'webhost'  => JURI::root(),
            'db' => array(
                'adapter' => $adapter,
                'params'  => $parameters
            )
        );
        $config = new Zend_Config($configArray);
        return $config;
    }

    /* (non-PHPdoc)
     * @see system/application/classes/RM/RM_Connector#installDB()
     */
    public function installDB(){
        $sql = $this->getInstallSQL();
        $this->_parseSQL($sql);

        global $mainframe;
        $mainframe->redirect('?option=com_resmania&act=index&task=index');
    }

    /* (non-PHPdoc)
     * @see system/application/classes/RM/RM_Connector#uninstallDB()
     */
    public function uninstallDB(){
        $sql = $this->getUninstallSQL();
        $this->_parseSQL($sql);
    }

    /**
     * Invocate sql query
     *
     * @param $sql - sql query
     * @return null
     */
    protected function _parseSQL($sql){
        $db =& JFactory::getDBO();
        foreach ($sql as $command) {
            $command = trim($command);
            if ($command != "") {
                $db->setQuery($command);
                $db->query();
            }
        }
    }

    /**
     * Returns the Joomla Request HTTP object.
     *
     * @param null
     * @return object
     */
    public function getRequestHTTP(){
        $request = new RM_Joomla_Request_Http();
        return $request;
    }

    public function getUsersModel(){
        return new RM_Joomla_Model_Users();
    }

    /* (non-PHPdoc)
     * @see system/application/classes/RM/RM_Connector#getBackendJSFileURLs()
     */
    public function getBackendJSFileURLs(){
        $rootPath = $this->getRootPath();

        $path = array(
            'administrator',
            'components',
            'com_resmania',
            'classes',
            'RM',
            'Joomla',
            'js',
            'back'
        );
        $folder = $rootPath.DIRECTORY_SEPARATOR.implode(DIRECTORY_SEPARATOR, $path);

        $files = RM_Filesystem::getFiles($folder);

        $result = array();
        $url = implode('/', $path);
        foreach ($files as $file) {
            $result[] = $url.'/'.$file;
        }
        return $result;
    }

    /**
    * This returns the CMS borders, these are used ensure that the interface is rendered to a size
    * to take into account these settings.
    *
    * @return 	string	JS viewport variables.
    */
    public function getViewPortJsCode(){

        // get the Maximised state...
        $config = new RM_Config;
        $Maximised = $config->getValue('rm_config_admin_gui_maximised');

        if ($Maximised){
            return "
                RM.ViewPortSize.top = 10;
                RM.ViewPortSize.left = 10;
                RM.ViewPortSize.right = 10;
                RM.ViewPortSize.bottom = 10;
                ";
        } else {
            return "
                RM.ViewPortSize.top = 150;
                RM.ViewPortSize.left = 0;
                RM.ViewPortSize.right = 0;
                RM.ViewPortSize.bottom = 45;
                ";
        }
    }

    /**
     * Sets the Joomla page title
     *
     * @param string $title
     */
    public function setPageTitle($title){
        $document = JFactory::getDocument();
        $oldtitle = $document->getTitle();
        $document->setTitle($oldtitle." | ".$title);
    }
}